<template>
  <div class="app-container">
    <div class="filter-container">
      <el-form>
        <el-form-item>
          <el-button type="danger" icon="plus" v-if="hasPerm('role:add')" @click="showCreate">添加角色
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <el-row :gutter="20" style="margin-bottom: 20px;">
        <el-col :span="5">
          <p style="color: #989A9A;">系统菜单名</p>
          <el-input placeholder="输入角色名" v-model="searchParam.roleName" @keyup.enter.native="getList('search')"></el-input>
        </el-col>

        <el-col :span="4">
          <p>&nbsp;</p>
          <el-button type="danger" @click="getList('search')">搜索</el-button>
        </el-col>

      </el-row>
    <el-table :data="list" v-loading.body="listLoading" element-loading-text="拼命加载中" border fit
              highlight-current-row>
      <el-table-column align="center" label="序号" min-width="5%">
        <template slot-scope="scope">
          <span v-text="getIndex(scope.$index)"> </span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="角色" prop="roleName" min-width="10%"></el-table-column>
      <el-table-column align="center" label="菜单&权限" min-width="70%">
        <template slot-scope="scope">
          <strong v-if="scope.row.id === 5"><h1>抱歉，有权限是真的可以为所欲为！</h1></strong>
          <div v-else v-for="menu in scope.row.menus" style="text-align: left" >
            <span style="width: 100px;display: inline-block;text-align: right; ">{{menu.menuName}}&nbsp;&nbsp;&nbsp;</span>
            <el-tag v-for="perm in menu.permissionList" :key="perm.id" v-text="perm.permissionName"
                    style="margin-right: 3px;"
                    type="danger"></el-tag>
          </div>
        </template>
      </el-table-column>
      <el-table-column align="center" label="管理" min-width="20%">
        <template slot-scope="scope">
          <el-button type="danger" icon="edit" @click="showUpdate(scope.$index)" v-if="hasPerm('role:edit') && scope.row.id !== 5">修改
          </el-button>
          <el-button v-if="hasPerm('role:delete') && scope.row.id !== 5" type="danger"
                      icon="delete"
                      @click="removeRole(scope.$index)">
            删除
          </el-button>
          <strong v-if="scope.row.id === 5"><h1>抱歉，有权限是真的可以为所欲为！</h1></strong>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="listQuery.pageNum"
        :page-size="listQuery.pageSize"
        :total="totalCount"
        layout="prev, pager, next">
    </el-pagination>
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
      <el-form class="small-space" :model="tempRole" label-position="left" label-width="100px"
               style='width: 800px; margin-left:50px;'>
        <el-form-item label="角色名称" required>
          <el-input type="text" v-model="tempRole.roleName" style="width: 250px;">
          </el-input>
        </el-form-item>
        <el-form-item label="菜单&权限" required>
          <div v-for=" (menu,_index) in allMenu" :key="menu.id">
            <span style="width: 100px;display: inline-block;">
              <el-button :type="isMenuNone(_index)?'':(isMenuAll(_index)?'danger':'primary')" size="mini"
                         style="width:100px;"
                         @click="checkAll(_index)">{{menu.menuName}}</el-button>
            </span>
            <div style="display: inline-block;margin-left:20px;">
              <el-checkbox-group v-model="tempRole.permissionList">
                <el-checkbox v-for="perm in menu.permissionList" :label="perm.id" @change="checkRequired(perm,_index)"
                             :key="perm.id">
                  <span :class="{requiredPerm:perm.remark === '1'}">{{perm.permissionName}}</span>
                </el-checkbox>
              </el-checkbox-group>
            </div>
          </div>
          <p style="color:#848484;">说明:红色权限为对应菜单内的必选权限</p>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button v-if="dialogStatus=='create'" type="danger" @click="createRole">创 建</el-button>
        <el-button type="danger" v-else @click="updateRole">修 改</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        list: [],//表格的数据
        allMenu: [],
        listLoading: false,//数据加载等待动画
        listQuery: {
          pageNum: 1,//页码
          pageSize: 15,//每页条数
          roleName: '',
          menuName: ''
        },
        searchParam: {
          roleName: ''
        },
        totalCount: 0,
        dialogStatus: 'create',
        dialogFormVisible: false,
        textMap: {
          update: '编辑',
          create: '新建角色'
        },
        tempRole: {
          roleName: '',
          id: '',
          permissionList: [],
        },
        adminName: '管理员'
      }
    },
    created() {
      this.getList()
      this.getAllMenu()
    },
    methods: {
      async getAllMenu() {
        const res = await this.$api.sysmenu.list(1, 1, false)
        this.allMenu = res.data
        console.log(this.allMenu)
      },
      async getList(search) {
        this.listLoading = true
        const res = (search && search === 'search') ? 
          await this.$api.sysrole.search(this.listQuery.pageSize, this.listQuery.pageNum, this.searchParam)
          : await this.$api.sysrole.list(this.listQuery.pageSize, this.listQuery.pageNum, true)
        this.listLoading = false
        this.list = res.data.data
      },
      handleSizeChange(val) {
        //改变每页数量
        this.listQuery.pageSize = val
        // this.handleFilter();
      },
      handleCurrentChange(val) {
        //改变页码
        this.listQuery.pageNum = val
        this.getList()
      },
      getIndex($index) {
        //表格序号
        return $index + 1
      },
      showCreate() {
        //显示新增对话框
        this.tempRole.roleName = ''
        this.tempRole.id = ''
        this.tempRole.permissionList = []
        this.dialogStatus = "create"
        this.dialogFormVisible = true
      },
      showUpdate($index) {
        let role = this.list[$index]
        this.tempRole.roleName = role.roleName
        this.tempRole.id = role.id
        this.tempRole.permissionList = []
        for (let i = 0; i < role.menus.length; i++) {
          let perm = role.menus[i].permissionList
          for (let j = 0; j < perm.length; j++) {
            this.tempRole.permissionList.push(perm[j].id)
          }
        }
        this.dialogStatus = "update"
        this.dialogFormVisible = true
      },
      async createRole() {
        if (!this.checkRoleNameUnique()) {
          return;
        }
        if (!this.checkPermissionNum()) {
          return;
        }
        await this.$api.sysrole.add(this.tempRole)
        this.getList();
        this.dialogFormVisible = false
      },
      async updateRole() {
        if (!this.checkRoleNameUnique(this.tempRole.id)) {
          return;
        }
        if (!this.checkPermissionNum()) {
          return;
        }
        await this.$api.sysrole.edit(this.tempRole)
        this.getList();
        this.dialogFormVisible = false
      },
      checkPermissionNum() {
        //校验至少有一种权限
        if (this.tempRole.permissionList.length === 0) {
          this.$message.error("请至少选择一种权限")
          return false
        }
        return true
      },
      checkRoleNameUnique(roleId) {
        //校验名称重复
        let roleName = this.tempRole.roleName
        if (!roleName) {
          this.$message.error("请填写角色名称")
          return false
        }
        let roles = this.list
        let result = true
        for (let j = 0; j < roles.length; j++) {
          if (roles[j].roleName === roleName && (!roleId || roles[j].id !== roleId  )) {
            this.$message.error("角色名称已存在")
            result = false
            break
          }
        }
        return result
      },
      removeRole($index) {
        let _vue = this;
        this.$confirm('确定删除此角色?', '提示', {
          confirmButtonText: '确定',
          showCancelButton: false,
          type: 'warning'
        }).then(async () => {
          let role = _vue.list[$index]
          await _vue.$api.sysrole.delete(role.id)
          _vue.getList()
          _vue.$message.success('删除成功')
        })
      },
      isMenuNone(_index) {
        //判断本级菜单内的权限是否一个都没选
        let menu = this.allMenu[_index].permissionList
        let result = true
        for (let j = 0; j < menu.length; j++) {
          if (this.tempRole.permissionList.indexOf(menu[j].id) > -1) {
            result = false
            break
          }
        }
        return result
      },
      isMenuAll(_index) {
        //判断本级菜单内的权限是否全选了
        let menu = this.allMenu[_index].permissionList
        let result = true
        for (let j = 0; j < menu.length; j++) {
          if (this.tempRole.permissionList.indexOf(menu[j].id) < 0) {
            result = false
            break
          }
        }
        return result;
      },
      checkAll(_index) {
        //点击菜单   相当于全选按钮
        let v = this
        if (v.isMenuAll(_index)) {
          //如果已经全选了,则全部取消
          v.noPerm(_index)
        } else {
          //如果尚未全选,则全选
          v.allPerm(_index)
        }
      },
      allPerm(_index) {
        //全部选中
        let menu = this.allMenu[_index].permissionList
        for (let j = 0; j < menu.length; j++) {
          this.addUnique(menu[j].id, this.tempRole.permissionList)
        }
      },
      noPerm(_index) {
        //全部取消选中
        let menu = this.allMenu[_index].permissionList
        for (let j = 0; j < menu.length; j++) {
          let idIndex = this.tempRole.permissionList.indexOf(menu[j].id)
          if (idIndex > -1) {
            this.tempRole.permissionList.splice(idIndex, 1)
          }
        }
      },
      addUnique(val, arr) {
        //数组内防重复地添加元素
        let _index = arr.indexOf(val)
        if (_index < 0) {
          arr.push(val)
        }
      },
      checkRequired(_perm, _index) {
        //本方法会在勾选状态改变之后触发
        let permId = _perm.id
        if (this.tempRole.permissionList.indexOf(permId) > -1) {
          //选中事件
          //如果之前未勾选本权限,现在勾选完之后,tempRole里就会包含本id
          //那么就要将必选的权限勾上
          this.makeReuqiredPermissionChecked(_index)
        } else {
          //取消选中事件
          if (_perm.remark === '1') {
            //如果是必勾权限,就把本菜单的权限全部移出
            //(其实也可以提示用户本权限是菜单里的必选,请先取消勾选另外几个权限,交互太麻烦,此处就直接全部取消选中了)
            this.noPerm(_index)
          }
        }
      },
      makeReuqiredPermissionChecked(_index) {
        //将本菜单必选的权限勾上
        let menu = this.allMenu[_index].permissionList
        for (let j = 0; j < menu.length; j++) {
          let perm = menu[j]
          if (perm.remark === '1') {
            //找到本菜单的必选权限,将其勾上
            this.addUnique(perm.id, this.tempRole.permissionList)
          }
        }
      }
    }
  }
</script>
<style scoped>
  .requiredPerm {
    color: #ff0e13;
  }
</style>
